package me.stone.stanimeclient.util

import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
import java.lang.IllegalArgumentException
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty

class AutoClearedValue<V: Any, T: LifecycleOwner>(
    private val owner: T,
    handle: ((T, AutoClearedValue<V, T>) -> Unit)? = null
): ReadWriteProperty<T, V> {

    private var _value: V? = null

    init {
        handle?.let {
            it(owner, this)
        }
    }

    fun _setNull() {
        _value = null
    }

    override fun getValue(thisRef: T, property: KProperty<*>): V {
        return _value ?: throw IllegalArgumentException("auto clear value maybe not available")
    }

    override fun setValue(thisRef: T, property: KProperty<*>, value: V) {
        _value = value
    }

}

fun <V: Any> AppCompatActivity.autoCleared() = AutoClearedValue<V, AppCompatActivity>(
    this
) { activity, value ->
    activity.lifecycle.addObserver(object: DefaultLifecycleObserver {
        override fun onDestroy(owner: LifecycleOwner) {
            value._setNull()
        }
    })
}

/*
    Fragment 的生命周期如下
    onAttach() -> onCreate() -> onCreateView() -> onActivityCreate() -> onStart()
     -> onResume() -> onPause() -> onDestroyView() -> onDestroy() -> onDetach()

    fragment 在 stack 中切换指挥在
    onCreateView() <-> onDestroyView() 之间执行，并不会执行 onCreate() 和 onDestroy()

    viewLifecycleOwner 会在 onCreateView() 之前被创建 在 onDestroyView() 之后被销毁
    viewLifecycleOwner 可以感知 Fragment 中 View 的生命周期和 stack 中的行为基本一致

    当在 Fragment 中使用生命周期感知建议使用 viewLifecycleOwner 来保证属性和 Fragment 行为一致
 */
fun <V: Any> Fragment.autoCleared() = AutoClearedValue<V, Fragment>(
    this
) { fragment, value ->
    fragment.lifecycle.addObserver(object: DefaultLifecycleObserver {
        override fun onCreate(owner: LifecycleOwner) {
            // 当前 viewLifecycleOwner 可能还未被创建，可以使用 viewLifecycleOwnerLiveData 观察它的创建
            viewLifecycleOwnerLiveData.observe(fragment) {
                it.lifecycle.addObserver(object: DefaultLifecycleObserver {
                    override fun onDestroy(owner: LifecycleOwner) {
                        value._setNull()
                    }
                })
            }
        }
    })
}

